package com.ruoyi.web.admin.data.command;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.domain.SysDevice;
import com.ruoyi.system.domain.SysHealthData;
import com.ruoyi.system.domain.qo.HealthDataQo;
import com.ruoyi.system.service.ISysAlertService;
import com.ruoyi.system.service.ISysDeviceCollectRecordService;
import com.ruoyi.system.service.ISysDeviceService;
import com.ruoyi.system.service.ISysHealthDataService;
import com.ruoyi.web.admin.data.Constants;
import com.ruoyi.web.admin.data.utils.CommonUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 健康数据上报命令处理器
 *
 * @author 10100
 */
@Component
public class HealthDataCommandHandler implements CommandHandler {

    private static final Logger log = LoggerFactory.getLogger(HealthDataCommandHandler.class);

    @Resource
    private ISysDeviceService sysDeviceService;

    @Resource
    private ISysHealthDataService sysHealthDataService;

    @Resource
    private ISysAlertService sysAlertService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private ISysDeviceCollectRecordService sysDeviceCollectRecordService;

    @Override
    public String handle(String deviceId, String iccid, String recordId, String command,
                         String type, String timestamp, String length, String body) {
        log.info("设备[{}]心率数据上报：{}", deviceId, body);
        //更新设备与健康数据
        try {
            // 解析心率数据并存储到数据库
            String[] healthData = body.split("@");
            String bloodOxygen = healthData[0];
            String heartRate = healthData[1];
            //String temperature = healthData[2];
            String wearStaus = healthData[3];

            SysDevice device = sysDeviceService.selectSysDeviceByeIdentifier(deviceId);
            if (device != null) {
                device.setWearStatus(wearStaus);
                device.setConnectionStatus("1");
                device.setLastHeartbeatTime(new Date());
                sysDeviceService.updateSysDevice(device);

                sysDeviceCollectRecordService.insertRecord(device, "WEAR_STATUS", wearStaus, "0未佩戴 1已佩戴");
            } else {
                // 设备不存在，创建新设备记录
                log.info("设备[{}]不存在，健康数据忽略", deviceId);
                return null;
            }

            /*未佩戴状态下， 不上报数据*/
            if (StringUtils.equals(wearStaus, "1") && !(StringUtils.equals("0", heartRate) && StringUtils.equals("0", bloodOxygen))) {
                boolean isValid = false;

                if (StringUtils.equals("0", heartRate)) {
                    isValid = true;
                } else {
                    // 使用Redis单key存储和判断心率无效值
                    int curHr = Integer.parseInt(heartRate);
                    String keyPattern = "heart_rate:" + device.getDeviceId() + ":*";
                    // 获取所有该设备3分钟内的心率key
                    Set<String> keys = redisTemplate.keys(keyPattern);
                    double avg = 0;
                    int count = 0;
                    if (!keys.isEmpty()) {
                        for (String key : keys) {
                            String val = redisTemplate.opsForValue().get(key);
                            if (StringUtils.isNotBlank(val)) {
                                int hr = Integer.parseInt(val);
                                avg += hr;
                                count++;
                            }
                        }
                        if (count > 0) {
                            avg = avg / count;
                            if (Math.abs(curHr - avg) / avg > 0.3) {
                                log.info("设备[{}]心率数据无效，当前值：{}，3分钟均值：{}，不予存储", deviceId, curHr, avg);
                            } else {
                                isValid = true;
                                log.info("设备[{}]心率数据，当前值：{}，3分钟均值：{}", deviceId, curHr, avg);
                            }
                        }
                    } else {
                        isValid = true;
                    }
                    // 存储本次心率数据到Redis
                    String curKey = "heart_rate:" + device.getDeviceId() + ":" + System.currentTimeMillis();
                    redisTemplate.opsForValue().set(curKey, String.valueOf(curHr), 3, TimeUnit.MINUTES);
                }

                if (isValid) {
                    SysHealthData sysHealthData = new SysHealthData();
                    sysHealthData.setDeviceId(device.getDeviceId());
                    sysHealthData.setUserId(device.getBindUserId());
                    sysHealthData.setRequestId(recordId);
                    sysHealthData.setUpdateTime(new Date());
                    sysHealthData.setBloodOxygen(bloodOxygen);
                    sysHealthData.setHeartRate(heartRate);
                    sysHealthData.setCreateTime(new Date());
                    sysHealthData.setRemark(body);
                    sysHealthDataService.insertSysHealthData(sysHealthData);

                    // 调用generateAlertsFromHealthData生成报警数据
                    sysAlertService.generateAlertsFromHealthData(sysHealthData);
                }
            }
        } catch (Exception e) {
            log.error("更新设备[{}]状态时发生错误: {}", deviceId, e.getMessage(), e);
        }

        // 构建响应格式
        String responseBody = "0";
        return "[" + deviceId + "," +
                iccid + "," +
                CommonUtils.generateSerialNumber() + "," +
                command + "," +
                Constants.REPORT_RESPONSE + "," +
                CommonUtils.getCurrentTimestamp() + "," +
                responseBody.length() + "," +
                responseBody + "]";
    }

    @Override
    public String getCommandType() {
        return "REPORT_HEART_HEALTH";
    }
}